console.inspectEnable = true
import EventEmitter from 'events';
import mqtt from 'mqtt';
import socket from 'socket';
import { ICallBack } from '../../interfaces/api.interface';
import { IMqttConnectParames } from './type';

class mqttManager extends EventEmitter {
  private client: any = null;

  constructor() {
    super()
  }

  /* 打开MQTT */
  private openMqtt(hostname = '192.168.128.1', port = 1883) {
    console.log('start open mqtt: ', hostname, port)
    try {
      const serAddr = socket.sockaddr(hostname, port);
      this.client = mqtt.open(serAddr, undefined, 5000);
      if (!this.client) {
        return { result: false, message: 'Can not connect to broker.' }
      }
      return { result: true, message: 'connect success.' }
    } catch (error) {
      console.error('[MQTT open]: ', error)
      return { result: false, message: 'Failed to connect to broker.' }
    }
  }

  /* 连接MQTT服务 */
  connectServer(params: IMqttConnectParames = { hostname: '192.168.128.1', port: 1883, client: 'Spirit', user: 'user', passwd: 'passwd' }, cb: ICallBack) {
    console.log('start connect server')
    if (this.getMqttClientStatus()) {
      return cb && cb({ result: true, message: 'Successfully connected to mqtt' })
    }
    const { hostname, port } = params
    try {
      const res = this.openMqtt(hostname, port)
      console.log('open mqtt result: ', res)
      if (res.result) {
        this.client.connect(params, () => {
          console.log(`${hostname}:${port} MQTT server connected!`);
        });

        this.client.on('connect', () => {
          this.emit('connect')
          console.info('mqtt client connect broker!');

          this.client.subscribe('message', { qos: 1 }, (error: any) => {
            if (error) {
              // 说明mqtt监听message事件失败！
              console.log('[MQTT subscribe message]: error')
            } else {
              console.log(`${hostname}:${port} MQTT server subscribed!`);
            }
          });

          // setInterval(() => {
          //   this.sendMessage('message', 'my mqtt')
          // }, 3000)

          cb && cb({ result: true, message: 'Successfully connected to mqtt' })
        });


        this.client.on('disconnect', () => {
          this.emit('disconnect')
          console.error('Lost broker!');
          // setTimeout(() => {
          //   this.connectServer(params)
          // }, 2000);
          this.connectServer(params, null)
          const t = setTimeout(() => {
            if (!this.client || !this.client.isConnected()) {
              this.connectServer(params, null)
            } else {
              clearTimeout(t)
            }
          }, 3000);
        });

        this.client.on('close', () => {
          console.info('mqtt client close!');
        });

        this.client.on('error', () => {
          console.error('mqtt client error!');
        });

        this.client.on('message', (data) => {
          console.log(`recevied a message from mqtt: ${JSON.stringify(data)}`);
          this.emit(data.topic, data.message.toString())
        });
      } else {
        cb && cb(res)
      }

    } catch (error) {
      console.error('[MQTT connectServer]: ', error)
      cb && cb({ result: false, message: 'Failed to connect to mqtt.' })
    }
  }

  /* 关闭与MQTT服务之间的连接 */
  disconnectServer() {
    this.client && this.client.close();
    this.emit('disconnect')
  }

  /* 发布消息 */
  sendMessage(topic: string, message: string) {
    this.client && this.client.publish(topic, message, { qos: 1 }, (error) => {
      if (error) {
        console.error('MQTT publish error:', error);
      } else {
        console.log('MQTT publish success: ', topic, message);
      }
    });
  }

  // 获取当前mqtt客户端状态
  getMqttClientStatus() {
    return this.client && this.client.isConnected();
  }
}

export default new mqttManager();